iT邦幫忙

2024 iThome 鐵人賽

DAY 6
1
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 6

Day06 Vue.js 簡單迷人的網頁動態效果 - 過渡類別篇

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240920/20124462L1T9rnK3MX.jpg

Vue 過渡類別的關鍵控制:讓動態設計成為過程的藝術

在現代動態設計中,過程的流暢性往往比最終的結果更能吸引使用者的目光。

Vue 的過渡類別不僅能幫助我們設計出精美的動效,更能將每一個動作細膩地表現出來,讓動態不再僅僅是視覺上的變化,而是充滿韻律與故事感的藝術。

為什麼過渡類別如此重要?

過渡類別可以讓元素的進場和離場變得更自然且引人入勝,不僅是設計的點綴,更是使用者體驗的升級。
例如在商業網站中,產品展示、創意作品集等應用場景,這些過渡效果都能讓頁面切換更順暢,並增添整體的精緻感,增加瀏覽率。


實作:打造一個商業級的 Page Transition 滑頁效果

Page Transition 滑頁效果是現代網站中不可或缺的過渡技巧之一。

無論是產品展示、電商平台還是創意作品集,這些過渡類別總是能在關鍵時刻出現,讓頁面切換更順。
當用得恰到好處,不僅讓畫面更靈動,還能給人一種高質感的視覺享受!


img

檔案架構

  • 首先是PageTransition.vue父元件

    • 第一頁:PageTransitionStart.vue
    • 第二頁:PageTransitionNext.vue
    • 第三頁:PageTransitionEnd.vue,再下一頁會回到第一頁
  • 主要程式碼(PageTransition.vue)

<script lang="ts" setup>
import { shallowRef, computed, defineAsyncComponent } from 'vue';

// 定義我們的每頁component
enum Pages {
  Start = 'start',
  Next = 'next',
  End = 'end', // 新增頁面作為示例
}

// 定義頁面元件與背景顏色的配置
const pageConfig = {
  [Pages.Start]: {
    component: defineAsyncComponent(() => import('./PageTransitionStart.vue')),
    color: 'bg-[#f1c40f]'
  },
  [Pages.Next]: {
    component: defineAsyncComponent(() => import('./PageTransitionNext.vue')),
    color: 'bg-[#e67e22]'
  },
  [Pages.End]: {
    component: defineAsyncComponent(() => import('./PageTransitionEnd.vue')), 
    color: 'bg-green-300'
  }
};

const page = shallowRef(Pages.Start);
// 使用 pageConfig 獲取對應的元件和背景顏色
const getComponent = computed(() => pageConfig[page.value].component);
const containerBgColor = computed(() => pageConfig[page.value].color);

const changePage = (newPage: Pages) => {
  page.value = newPage;
};
</script>

<template>
  <div :class="['relative w-full h-screen overflow-hidden', containerBgColor]">
    <transition name="slide" mode="out-in">
      <component :is="getComponent" @change-page="changePage" />
    </transition>
  </div>
</template>

<style scoped>

.slide-enter-from {
  transform: translateX(100%);
}
.slide-enter-active, .slide-leave-active {
  position: absolute;
  width: 100%;
  transition: transform 0.5s ease;
}
.slide-leave-to {
  transform: translateX(-100%);
}
.slide-enter-to, .slide-leave-from {
  transform: translateX(0);
}
</style>



解構第一頁的進場過渡與離場過渡

<style scoped>

.slide-enter-from {
  transform: translateX(100%);
}
.slide-enter-active, .slide-leave-active {
  position: absolute;
  width: 100%;
  transition: transform 0.5s ease;
}
.slide-leave-to {
  transform: translateX(-100%);
}
.slide-enter-to, .slide-leave-from {
  transform: translateX(0);
}

</style>

  • 進場流程

  • 元素從右側滑入 (slide-enter-from) → 過渡過程中保持絕對位置與寬度 (slide-enter-active) → 最終到達正中位置 (slide-enter-to)。

  • 離場流程

  • 元素從正中開始 元素從正中開始 (slide-leave-from) → 過渡過程中保持絕對位置與寬度 (slide-leave-active) → 最後滑出到左側 (slide-leave-to)

子元件程式碼

  • 第一頁程式碼:PageTransitionStart.vue
<script lang="ts" setup>
//定義事件 defineEmits
const emit = defineEmits(['change-page']);
</script>

<template>
<transition name="slide">

  <div class="grid w-full grid-cols-[repeat(auto-fit,_minmax(400px,_1fr))]">
    <transition name="fade">
      <div
        class="grid h-screen items-center justify-center bg-[var(--bg-color)]"
        :style="{ '--bg-color': '#f1c40f' }"
      >
      // 換頁方法
      // 當按鈕被點擊時,`@click` 會監聽到這個事件並執行 `emit('change-page', 'next')`
        <button
          @click="emit('change-page', 'next')"
          class="btn-jittery text-8 font-mono bg-transparent
             text-white 
             border-3 border-solid border-white rounded-full px-8 py-3 
             outline-none cursor-pointer tracking-[2px]
             animate-[jittery_4s_infinite] hover:animate-[heartbeat_0.2s_infinite]
             "
        >
          Start !
        </button>
      </div>
    </transition>
  </div>

</transition>
</template>
<style>
/* Vue Transition Styles */
.fade-enter-active,
.fade-leave-active {
  transition: all 0.2s ease-in-out;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@keyframes jittery {
  0%, 50% { transform: scale(1); }
  10% { transform: scale(0.9); }
  15% { transform: scale(1.15); }
  20% { transform: scale(1.15) rotate(-5deg); }
  25% { transform: scale(1.15) rotate(5deg); }
  30% { transform: scale(1.15) rotate(-3deg); }
  35% { transform: scale(1.15) rotate(2deg); }
  40% { transform: scale(1.15) rotate(0); }
}

@keyframes heartbeat {
  50% {
    transform: scale(1.1);
  }
}
</style>
  • 第二頁:PageTransitionNext.vue
//.... 其他重複先省略

    <transition name="fade">
      <div
        class="grid h-screen items-center justify-center bg-[var(--bg-color)]"
        :style="{ '--bg-color': '#e67e22' }"
      >
        <button
          @click="emit('change-page', 'start')"
          class="btn-jittery text-8 font-mono bg-transparent
             text-white 
             border-3 border-solid border-white rounded-full px-8 py-3 
             outline-none cursor-pointer tracking-[2px]
             animate-[jittery_4s_infinite] hover:animate-[heartbeat_0.2s_infinite]
             "
        >
          End !
        </button>
      </div>
    </transition>
//....

  • 第三頁:PageTransitionEnd.vue
//....與前面兩頁一樣,僅提供差異處
// 定義此頁背景色

<div class="grid h-screen items-center justify-center bg-[var(--bg-color)]"
	:style="{ '--bg-color': '#e67e22' }"
>	
// emit('change-page','start') 帶入第一頁參數,下一頁就又回到第一頁了
	<button @click="emit('change-page', 'start')" class="..."></button>

Vue 過渡類別(Transition Classes)的核心運用

Vue 的過渡類別的執行過程,主要應用於 初始化與加載結尾與退出 這兩個核心階段。
中間的 瀏覽與互動階段 會使用 CSS 動畫(@keyframes)或是JavaScript、GSAP等等來進行。

進場動效順序

  • v-enter-fromv-enter-activev-enter-to

離場動效順序

  • v-leave-fromv-leave-activev-leave-to

過渡類別的詳細說明

v-enter-from 前面的v就是我們自定義的class名稱。

進場動效

  1. 初始化開始

    • v-enter-from:元素剛插入時的初始狀態(通常是隱藏的狀態)。這是動效的起點,常使用 CSS 設置透明度為 0 或將元素移出視窗範圍。
  2. 活動狀態

    • v-enter-active:進場動效進行中的狀態,從元素插入到動效完成的整個過程。這裡可調整動效的時間、延遲和緩動曲線,例如:transition: all 0.5s ease-in-out;
  3. 動效完成

    • v-enter-to:進場動效的結束狀態。這個類別在動效的最後應用,代表元素已完全顯示。

離場動效

  1. 初始狀態

    • v-leave-from:觸發離場動效時的初始狀態(通常是元素顯示的狀態)。應用於動效開始時。
  2. 活動狀態

    • v-leave-active:離場動效進行中的狀態,應用於動效的整個過程中。可設置離場動效的時間、延遲和緩動曲線。
  3. 動效完成

    • v-leave-to:離場動效的結束狀態。這個類別在離場動效的第一幀後應用,並在動效結束時移除,通常代表元素隱藏的狀態。

小提示:提升過渡設計的實用性

  • 一致性與統一性:網站的所有動效應風格統一,這樣能避免視覺疲勞,並強化品牌識別。
  • 跨設備適配:確保過渡效果在所有裝置上都保持一致,無論是手機、平板還是桌機,都應該有同樣的視覺體驗。
  • 避免過度使用:過多的過渡效果可能會導致使用者分心或感到煩躁,過渡應該適時適量。

結語:讓動態成為你的專屬設計語言

掌握 Vue 過渡類別後,你會發現這不僅僅是動效工具,而是一種設計語言,讓你在網站設計上能有更多創意的表現空間。

希望你能夠將這些過渡類別運用到你的專案中,並持續探索動態設計的無限可能。


上一篇
Day05 Vue.js 簡單迷人的網頁動態效果 - 解析流程篇
下一篇
Day07 Vue.js 簡單迷人的網頁動態效果 - 鉤子 Hooks 篇
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言